import numpy as np
import matplotlib.pyplot as plt
from skimage import color, filters, exposure
pierre = plt.imread("pierre.jpg")
pierre2gray = color.rgb2gray(pierre); # On transforme l'image en niveau de gris
plt.imshow(pierre)
L’égalisation par histogramme permet de régler le contraste d’une image. nous traçons d'abord l'histogramme de la distribution d'intensité des pixels, puis on le modifie. Il existe une fonction de probabilité cumulative associée à chaque image. L’égalisation par histogramme donne une tendance linéaire à cette fonction. Nous utilisons une image en niveaux de gris pour effectuer l'égalisation de l'histogramme.
_, ax = plt.subplots(1, 2, figsize=(10,5))
_ = ax[0].imshow(pierre2gray, cmap="gray")
_ = ax[1].hist(pierre2gray.flatten(), bins=256)
Elle représente le nombre de pixels en fonction du niveau de gris
pierre2gray_eq = exposure.equalize_hist(pierre2gray)
_, ax = plt.subplots(1, 2, figsize=(10,5))
_ = ax[0].imshow(pierre2gray_eq, cmap="gray")
_ = ax[1].hist(pierre2gray_eq.flatten(), bins=256)
On a une meilleure repartition des intensités sur l'ensemble de la plage de valeurs possibles en etalant l'histogramme
On voit nettement l’amélioration produite par l’application de l’algorithme d’égalisation. L’image originale était une image sombre, en effet la majeure partie de l’histogramme est avant 0.5 qui représentent les niveaux de gris « sombre ». L’algorithme a donc étalé la dynamique, mais il a aussi équilibré les niveaux de gris. Ainsi, les niveaux de gris ne sont plus concentrés avant 0.5, mais on a quasiment autant de pixels avec un niveau de gris supérieur à 0.5 que de pixels avec un niveau de gris inférieur à 0.5. Sur l’image originale, on distinguait pas vraiment l'animal qui etait sur la pierre, tandis que sur l’image égalisée, c’est flagrant, on le distingue parfaitement et mêmes certains détails quasiment invisibles au préalable apparaissent.
Le seuillage d'image est une technique simple de binarisation d'image, elle consiste à transformer une image en niveau de gris en une image dont les valeurs de pixels ne peuvent avoir que la valeur 1 ou 0
pierre2bit = np.where(pierre2gray>=pierre2gray.mean(),1,0) # Seuillage avec la moyenne des pixels comme seuil
plt.imshow(pierre2bit, cmap="gray")
from skimage.morphology import selem, erosion
els_disk = selem.disk(3)
pierre2bit_erosion = erosion(pierre2bit, els_disk)
_, ax = plt.subplots(1, 3, figsize=(15,8))
_ = ax[0].imshow(pierre2gray, cmap="gray")
_ = ax[1].imshow(pierre2bit, cmap="gray")
_ = ax[2].imshow(pierre2bit_erosion, cmap="gray")
L'erosion (l'image de droite) efface les éléments clairs l'image est plus sombre L'image du milieu n'est rien d'autre que l'image binarisé (blanc et noir) de l'image de gauche
lena = plt.imread("lena.jpg")
lena2gray = color.rgb2gray(lena) # A
_, ax = plt.subplots(1,2, figsize=(15,10))
_ = ax[0].imshow(lena, cmap="gray")
ax[0].set_title("Image original")
_ = ax[1].imshow(lena2gray, cmap="gray")
ax[1].set_title("Image en niveaux de gris")
l'image de gauche original et l'image de droite correspond a l'image mise en niveaux de gris
# Plage de valeur
lena2gray.min(), lena2gray.max()
La valeur minimale de pixel et la valeur maximal sont données ci-dessus cela nous permet de s'assurer que La plage des valeurs de l'image est bien comprise entre 0 et 1
from skimage import util
lena_noise_gaussian = util.random_noise(lena2gray, mode="gaussian") # AG
lena_noise_saltpapper = util.random_noise(lena2gray, mode="s&p") # ASP
_, ax = plt.subplots(1,2, figsize=(15,10))
_ = ax[0].imshow(lena_noise_gaussian, cmap="gray")
ax[0].set_title("Image avec bruit gaussien")
_ = ax[1].imshow(lena_noise_saltpapper, cmap="gray")
_=ax[1].set_title("Image avec bruit de type sel & poivre")
Image de gauche correspond à l'image bruité par le bruit gaussien et Image de droite correspond à l'image bruité par le bruit de type sel & poivre
from scipy.signal import freqz
w, h = freqz(F2.ravel(), a=1)
sr = 44100
x = w * sr * 1.0 / (2 * np.pi)
y = 20 * np.log10(abs(h))
plt.figure(figsize=(10,5))
plt.semilogx(x, y)
plt.ylabel('Amplitude [dB]')
plt.xlabel('Frequency [Hz]')
plt.title('reponse frequentielle filtre F2')
plt.grid(which='both', linestyle='-', color='grey')
plt.xticks([20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000], ["20", "50", "100", "200", "500", "1K", "2K", "5K", "10K", "20K"])
plt.show()
w, h = freqz(F3.ravel(), a=1)
sr = 44100
x = w * sr * 1.0 / (2 * np.pi)
y = 20 * np.log10(abs(h))
plt.figure(figsize=(10,5))
plt.semilogx(x, y)
plt.ylabel('Amplitude [dB]')
plt.xlabel('Frequency [Hz]')
plt.title('reponse frequentielle filtre F3')
plt.grid(which='both', linestyle='-', color='grey')
plt.xticks([20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000], ["20", "50", "100", "200", "500", "1K", "2K", "5K", "10K", "20K"])
plt.show()
Ces filtres sont des filtres passe bas car les frequences élevées sont atténuées
Le filtrage a pour but de réduire les effets du bruit sans affecter trop le signal
from scipy import ndimage
F2 = 1/9*np.ones(9).reshape(3,3)
F3 = 1/25*np.ones(25).reshape(5,5)
AG_f2 = ndimage.convolve(lena_noise_gaussian, F2)
AG_f3 = ndimage.convolve(lena_noise_gaussian, F3)
_, ax = plt.subplots(1,3, figsize=(15,10))
_ = ax[0].imshow(lena_noise_gaussian, cmap="gray")
ax[0].set_title("Image avec bruit gaussien")
_ = ax[1].imshow(AG_f2, cmap="gray")
ax[1].set_title("filtre avec F2")
_ = ax[2].imshow(AG_f3, cmap="gray")
_=ax[2].set_title("filtre avec F3")
Après avoir appliqué les differents filtres F2 et F3 ( qui sont les filtres moyenneur d'ordre 3 et 5) à l'image bruité par le bruit gaussien Nous obtenons les resultats ci dessus: On remarque toujours la presence de tâche blanche sur l'image du milieu pour le filtre F2 et après application du filtre F3 l'image (image de droite) qui comprenait toujours de tâche n'a pas subit d'amelioration elle devient plus flou
ASP_f2 = ndimage.convolve(lena_noise_saltpapper, F2)
ASP_f3 = ndimage.convolve(lena_noise_saltpapper, F3)
_, ax = plt.subplots(1,3, figsize=(15,10))
_ = ax[0].imshow(lena_noise_saltpapper, cmap="gray")
ax[0].set_title("Image avec bruit sel & poivre")
_ = ax[1].imshow(ASP_f2, cmap="gray")
ax[1].set_title("filtre avec F2")
_ = ax[2].imshow(ASP_f3, cmap="gray")
_=ax[2].set_title("filtre avec F3")
La même remarque pour le bruit de type sel et poivre toujours des tâches blanches sur l'image du milieu (filtre F2) et image flou pour l'image de droite(Filtre F3)
En conclusion: La taille du filtre moyenneur n'a pas d'effet positif sur les images bruités
rail = plt.imread("rail.jpg")
rail2gray = color.rgb2gray(rail)
_, ax = plt.subplots(1,2, figsize=(15,10))
_ = ax[0].imshow(rail, cmap="gray")
ax[0].set_title("Image Original")
_ = ax[1].imshow(rail2gray, cmap="gray")
_=ax[1].set_title(" image en niveaux de gris")
Comme d’autres transformations, la transformée en cosinus discrète (DCT) tente de décorréler l’image. Les données. Après décorrélation, chaque coefficient de transformation peut être codé indépendamment sans perdre l'efficacité de la compression
from scipy import fftpack
from sklearn.preprocessing import MinMaxScaler
s1_ = fftpack.dct(rail2gray)
s2_ = fftpack.fft2(rail2gray)
scaler_s1 = MinMaxScaler() # Normalise les donnees dans l'intervale 0-1
scaler_s2_reel = MinMaxScaler()
scaler_s2_imag = MinMaxScaler()
scaler_s1.fit(s1_)
scaler_s2_imag.fit(s2_.imag)
scaler_s2_reel.fit(s2_.real)
# Reccuperarion des compodantes
s1 = scaler_s1.transform(s1_)
s2_reel = scaler_s2_reel.transform(s2_.real)
s2_imag = scaler_s2_imag.transform(s2_.imag)
_, ax = plt.subplots(1,3, figsize=(15,10))
_ = ax[0].imshow(s1, cmap="gray")
ax[0].set_title("DCT")
_ = ax[1].imshow(s2_reel, cmap="gray")
ax[1].set_title("FFT réel")
_ = ax[2].imshow(s2_imag, cmap="gray")
_=ax[2].set_title("FFT imaginaire")
# Recupperation des 4/16 des index
XY = int(np.round(s1_.shape[0]*4/16))
# Ajout du cadre noir
s1_XY_0 = np.zeros((XY,XY))
s1[0:XY,0:XY] = s1_XY_0
# Reconstruction de l'image
s1_inv = scaler_s1.inverse_transform(s1)
is1 = fftpack.idct(s1_inv)
_, ax = plt.subplots(1,2, figsize=(15,10))
_ = ax[0].imshow(s1, cmap="gray")
ax[0].set_title("filtre spectral")
_ = ax[1].imshow(is1, cmap="gray")
_=ax[1].set_title("image filtrée")
On a un filtre haute fréquence le filtre utilisé se trouve au dessus de l'image
a = int(np.round(s2_.shape[0]*6/16))
b = int(np.round(s2_.shape[0]*10/16))
# Ajout du cadre noir
s2_ab_0 = np.zeros((abs(a-b),abs(a-b)))
s2_reel[a:b,a:b] = s2_ab_0
s2_imag[a:b,a:b] = s2_ab_0
_, ax = plt.subplots(1,2, figsize=(15,10))
_ = ax[0].imshow(s2_reel, cmap="gray")
ax[0].set_title("filtre spectral réel")
_ = ax[1].imshow(s2_imag, cmap="gray")
_=ax[1].set_title("filtre spectral imaginaire")
Le filtre etant au milieu la nature du filtrage est Basse frequence( BF)
s2_reel_inv = scaler_s2_reel.inverse_transform(s2_reel)
s2_imag_inv = scaler_s2_imag.inverse_transform(s2_imag)
is2_reel = fftpack.ifft2(s2_reel_inv)
is2_imag = fftpack.ifft2(s2_imag_inv)
_, ax = plt.subplots(1,2, figsize=(15,10))
_ = ax[0].imshow(rail2gray, cmap="gray")
ax[0].set_title("Image Original")
ax[1].imshow(abs(is2_reel), cmap="gray")
_=ax[1].set_title("image reconstitué")
L'image n'est pas bien reconstitué on voit certain contour